package org.hako.recite.word.test.impl.gui.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hako.recite.word.test.WordTestMode;
import org.hako.recite.word.test.WordTestProfile;
import org.hako.recite.word.test.impl.gui.NullWordTestBehavior;
import org.hako.recite.word.test.impl.gui.WordTestBehavior;

/**
 * Shell of word test settings.
 * 
 * @since 0.4.3
 * @author <a href="mailto:xnnyygn@gmail.com">xnnyygn</a>
 */
public class WordTestSettingShell extends AbstractReciteWordShell {

	private final static int X_CENTER_LINE = 40;
	private Combo cbTestMode;
	private Text txtWordLimit;
	private Text txtRangeStart;
	private Text txtRangeEnd;
	private Text txtQuestionFieldIndex;
	private Text txtAnswerFieldIndex;
	private Text txtWordOffset;
	private WordTestProfile profile;

	/**
	 * Create
	 */
	WordTestSettingShell() {
		this(null, new NullWordTestBehavior(), new WordTestProfile());
	}

	/**
	 * Create
	 * 
	 * @param parentShell
	 * @param behavior
	 * @param initalProfile
	 */
	public WordTestSettingShell(Shell parentShell, WordTestBehavior behavior,
			WordTestProfile initalProfile) {
		super(parentShell, SWT.DIALOG_TRIM, behavior);
		this.profile = initalProfile;
		shell.setText("Word Test Setting");
		FormLayout shellLayout = new FormLayout();
		shellLayout.marginHeight = 10;
		shellLayout.marginWidth = 10;
		shell.setLayout(shellLayout);
		addComponents(shell, initalProfile);
		shell.pack();
		
		// center in the middle
		center();
	}

	/**
	 * Add components to composite.
	 * 
	 * @param parentComposite
	 * @param initalProfile
	 */
	private void addComponents(Composite parentComposite,
			WordTestProfile initalProfile) {

		// add label test mode
		Label lbTestMode = createLabel("Test mode", parentComposite, null);

		// add combo test mode
		cbTestMode = new Combo(parentComposite, SWT.READ_ONLY);
		for (WordTestMode testMode : WordTestMode.values()) {
			cbTestMode.add(testMode.toString());
		}
		cbTestMode.select(initalProfile.getRandomMode());
		FormData formData = createRightSideFormData(lbTestMode, null);
		formData.width = 200;
		cbTestMode.setLayoutData(formData);

		// add label word limit
		Label lbWordLimit = createLabel("Word limit", parentComposite,
				lbTestMode);

		// add text word limit
		txtWordLimit = createText(parentComposite,
				String.valueOf(initalProfile.getWordLimit()));
		txtWordLimit.setLayoutData(createRightSideFormData(lbWordLimit,
				cbTestMode));

		// add label word offset
		Label lbWordOffset = createLabel("Word offset", parentComposite,
				lbWordLimit);

		// add text word offset
		txtWordOffset = createText(parentComposite,
				String.valueOf(initalProfile.getWordOffset()));
		txtWordOffset.setLayoutData(createRightSideFormData(lbWordOffset,
				txtWordLimit));

		// add label range start
		Label lbRangeStart = createLabel("Range start", parentComposite,
				lbWordOffset);

		// add text range start
		txtRangeStart = createText(parentComposite,
				String.valueOf(initalProfile.getWordRangeStart()));
		txtRangeStart.setLayoutData(createRightSideFormData(lbRangeStart,
				txtWordOffset));

		// add label range end
		Label lbRangeEnd = createLabel("Range end", parentComposite,
				lbRangeStart);

		// add text range end
		txtRangeEnd = createText(parentComposite,
				String.valueOf(initalProfile.getWordRangeEnd()));
		txtRangeEnd.setLayoutData(createRightSideFormData(lbRangeEnd,
				txtRangeStart));

		// add label question field index
		Label lbQuestionFieldIndex = createLabel("Question field index",
				parentComposite, lbRangeEnd);

		// add text question field index
		txtQuestionFieldIndex = createText(parentComposite,
				String.valueOf(initalProfile.getQuestionFieldIndex()));
		txtQuestionFieldIndex.setLayoutData(createRightSideFormData(
				lbQuestionFieldIndex, txtRangeEnd));

		// add label answer field index
		Label lbAnswerFieldIndex = createLabel("Answer field index",
				parentComposite, lbQuestionFieldIndex);

		// add text answer field index
		txtAnswerFieldIndex = createText(parentComposite,
				String.valueOf(initalProfile.getAnswerFieldIndex()));
		txtAnswerFieldIndex.setLayoutData(createRightSideFormData(
				lbAnswerFieldIndex, txtQuestionFieldIndex));

		// add button start
		createButtonStart(parentComposite, txtAnswerFieldIndex);
	}

	/**
	 * Create button start.
	 * 
	 * @param parentComposite
	 * @param topRelativeTo
	 * 
	 */
	private void createButtonStart(Composite parentComposite,
			Control topRelativeTo) {
		Button btnStart = new Button(parentComposite, SWT.PUSH);
		btnStart.setText("Start");
		FormData formData = new FormData();
		formData.width = 100;
		formData.left = new FormAttachment(X_CENTER_LINE, 3);
		formData.top = new FormAttachment(topRelativeTo, 5);
		btnStart.setLayoutData(formData);
		btnStart.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent event) {
				profile.setRandomMode(cbTestMode.getSelectionIndex());
				profile.setWordLimit(Integer.parseInt(txtWordLimit.getText()));

				// for learning
				profile.setWordOffset(Integer.parseInt(txtWordOffset.getText()));

				// for test
				profile.setWordRangeStart(Integer.parseInt(txtRangeStart
						.getText()));
				profile.setWordRangeEnd(Integer.parseInt(txtRangeEnd.getText()));

				profile.setQuestionFieldIndex(Integer
						.parseInt(txtQuestionFieldIndex.getText()));
				profile.setAnswerFieldIndex(Integer
						.parseInt(txtAnswerFieldIndex.getText()));
				behavior.showTestWindow(profile);
			}

		});
		shell.setDefaultButton(btnStart);
	}

	/**
	 * Create text.
	 * 
	 * @param parentComposite
	 * @param initalText
	 * @return
	 */
	private Text createText(Composite parentComposite, String initalText) {
		Text text = new Text(parentComposite, SWT.SINGLE | SWT.BORDER);
		text.setText(initalText);
		return text;
	}

	/**
	 * Create right side form data.
	 * 
	 * @param topRelativeTo
	 * @param rightRelativeTo
	 * @return
	 */
	private FormData createRightSideFormData(Control topRelativeTo,
			Control rightRelativeTo) {
		FormData formData = new FormData();
		formData.left = new FormAttachment(X_CENTER_LINE, 3);
		formData.top = new FormAttachment(topRelativeTo, 0, SWT.CENTER);
		if (rightRelativeTo != null) {
			formData.right = new FormAttachment(rightRelativeTo, 0, SWT.RIGHT);
		}
		return formData;
	}

	/**
	 * Create label.
	 * 
	 * @param text
	 * @param parentComposite
	 * @param relativeTo
	 * @return
	 */
	private Label createLabel(String text, Composite parentComposite,
			Control relativeTo) {
		Label label = new Label(parentComposite, SWT.NONE);
		label.setText(text);
		FormData formData = new FormData();
		formData.right = new FormAttachment(X_CENTER_LINE, -3);
		if (relativeTo != null) {
			formData.top = new FormAttachment(relativeTo, 10);
		}
		label.setLayoutData(formData);
		return label;
	}

}
